mod encode;
mod decode;

use std::collections::{HashMap, HashSet};
use std::ops::Deref;
use bytes::{BufMut, BytesMut};
use enum_dispatch::enum_dispatch;

#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct SimpleString(pub String);


impl SimpleString {
    pub fn new(s: &str) -> Self {
        SimpleString(s.to_string())
    }
}

#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct SimpleError(String);

impl SimpleError {

    pub fn new(s: &str) -> Self {
        SimpleError(s.to_string())
    }
}

#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct RespNull;

pub struct RespNullArray;

pub struct RespMap(HashMap<String, RespFrame>);

pub struct RespSet(HashSet<RespFrame>);

pub struct BulkString(Vec<u8>);

pub struct RespArray(Vec<RespFrame>);


// 2个 trait
pub trait RespEncode {
    fn encode(self) -> Vec<u8>;
}

// pub trait RespDecode {
//      fn decode(array: &[u8]) -> Result<RespFrame, String>;
// }


#[enum_dispatch(RespEncode)]
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum RespFrame {
    SimpleString(SimpleString),
    Error(SimpleError),
    Integer(i64),
    // BulkString(BulkString),
    // Array(RespArray),
    // NullArray(RespNullArray),
    Null(RespNull),
    // Boolean(bool),
    // Double(f64),
    // Map(RespMap),
    // Set(RespSet),
}


#[test]
fn test_bytes() {
    let mut buf = BytesMut::with_capacity(1024);
    buf.put(&b"hello world"[..]);
    buf.put_u16(1234);

    let a = buf.split();


    println!("a is {:?}", a);

    assert_eq!(a, b"hello world\x04\xD2"[..]);

    buf.put(&b"goodbye world"[..]);

    let b = buf.split();
    assert_eq!(b, b"goodbye world"[..]);

    assert_eq!(buf.capacity(), 998);
}


impl Deref for SimpleString {
    type Target = String;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl Deref for SimpleError {
    type Target = String;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl Deref for BulkString {
    type Target = Vec<u8>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl Deref for RespArray {
    type Target = Vec<RespFrame>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}


impl Deref for RespMap {
    type Target = HashMap<String, RespFrame>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}


impl Deref for RespSet {
    type Target = HashSet<RespFrame>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}
